#ifndef CUSTOM_RC_MERGE_INCLUDED
#define CUSTOM_RC_MERGE_INCLUDED

#include "RCCommon.hlsl"

// Uniform Parameter
uniform int Cascade_Level;                          // Current Cascade Level n
uniform Texture2D Cascade_MergeTex;                    // n + 1 Level Merge Result

Texture2D _BlitTexture;                             // Pre-calced RayMaching Result

float4 RCMergeFragment(Vert2Frag Input) : SV_TARGET {
    ProbeInfo Probe = GetProbeInfo(Cascade_Level, Input.ScreenUV);

    int AngleLocalIndex     = Probe.AngleLocalPix.x + Probe.AngleLocalPix.y * Probe.AngleSize.x;
    float2 AngleSize_Np1    = Cascade_ProbeSize_AngleSize[Cascade_Level + 1].zw;
    // Merge
    float4 LDResult = SampleCascade(Cascade_MergeTex, (Probe.Probe - 1) / 2 + int2(0, 0), AngleSize_Np1, AngleLocalIndex * 4, 4);
    float4 RDResult = SampleCascade(Cascade_MergeTex, (Probe.Probe - 1) / 2 + int2(1, 0), AngleSize_Np1, AngleLocalIndex * 4, 4);
    float4 LUResult = SampleCascade(Cascade_MergeTex, (Probe.Probe - 1) / 2 + int2(0, 1), AngleSize_Np1, AngleLocalIndex * 4, 4);
    float4 RUResult = SampleCascade(Cascade_MergeTex, (Probe.Probe - 1) / 2 + int2(1, 1), AngleSize_Np1, AngleLocalIndex * 4, 4);
        
    float BilinearU = 0.25 + 0.5 * ((Probe.Probe.x - 1) & 1);
    float BilinearV = 0.25 + 0.5 * ((Probe.Probe.y - 1) & 1);

    float4 MergeResult = float4(0, 0, 0, 0);
    // MergeResult = (LDResult + RDResult + LUResult + RUResult) / 4;
    // MergeResult = (LDResult * 0.75 + RDResult * 0.25) * 0.25 + (LUResult * 0.75 + RUResult * 0.25) * 0.75;

    MergeResult = BilinearLerp(LDResult, RDResult, LUResult, RUResult, float2(BilinearU, BilinearV));
    // MergeResult.rgb = MergeResult.rgb * MergeResult.a;
    // MergeResult = MergeResult / max(1e-2, MergeResult.a);
    
    // Deal With Marching Result
    float4 RayMarchingResult = _BlitTexture.Load(int3(Probe.TexPix, 0));

    float4 Result = RayMarchingResult;
    Result.rgb  = MergeResult.rgb * RayMarchingResult.a + RayMarchingResult.rgb;
    Result.a    = RayMarchingResult.a * MergeResult.a;
    // Result = (LDResult * 0.25 + RDResult * 0.75) * 0.25 + (LUResult * 0.25 + RUResult * 0.75) * 0.75;
    // Result = MergeResult;
    // Result = float4(BaseUV_Np1 + AngleUV_Np1, 0.0, 1.0);
    // Result = float4((Probe.Probe.x - 1) & 1, (Probe.Probe.y - 1) & 1, 0.0, 1.0);
    // Result = float4(AngleUV_Np1 * _ScreenParams.xy / 64.0, 0.0, 1.0);
    // Result = float4(float2(AngleIndex_Np1 - floor(AngleIndex_Np1 / ProbeSize_Np1.x) * ProbeSize_Np1.x, floor(AngleIndex_Np1 / ProbeSize_Np1.x)) / (1 << (Cascade_Level + 2)), 0.0, 1.0);
    // Result = float4(ProbeLocalTex_Np1 / ProbeSize_Np1, 0.0, 1.0);AngleIndex_Np1
    // Result = float4(AngleLocalIndex, AngleLocalIndex, AngleLocalIndex, 1.0) / Probe.ProbePixSize.x / Probe.ProbePixSize.y;
    // Result = float4(floor(AngleIndex_Np1 / ProbeSize_Np1.x), floor(AngleIndex_Np1 / ProbeSize_Np1.x), floor(AngleIndex_Np1 / ProbeSize_Np1.x), 1.0) / ProbeSize.x / ProbeSize.y * 16;

    // Result = RayMarchingResult;
    // Result = float4(Probe.Probe / Cascade_ProbeNum_TexSize[Cascade_Level].xy, 0.0, 1.0);

    return Result;
}
#endif